package cn.tedu.reflect;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;

public class Test3 {
    public static void main(String[] args) throws Exception {
     //   method();//暴力反射成员方法们
        //method2();//暴力反射成员变量
        method3();

    }

    public static void method3() throws Exception {
        //获取class对象
         Class a=Person.class;
         //获取show（）
        Method m = a.getDeclaredMethod("show");
        //获取test注解的标志
        //getDeclaredAnnotation（1）--参数是注解类型的class对象
        Test test = m.getDeclaredAnnotation(Test.class);
        Object o = a.newInstance();
        //有注解就运行
        if (test!=null){
            m.invoke(o);
        }
    }

    //暴力反射成员方法们
    private static void method() throws Exception {
        //获取class对象
        Class a = Person.class;
        ////调用方法暴力反射--getDeclaredMethods()获取所有成员方法--包括自己的方法
        Method[] ms = a.getDeclaredMethods();
        //遍历数组，得到每个方法m
        for (Method m : ms) {
            //获取方法名称
            System.out.println(m.getName());
            //获取方法的参数
            Class<?>[] cs = m.getParameterTypes();
            System.out.println(Arrays.toString(cs));

        }
        //暴力反射 某个方法
        //getDeclaredMethod(1,2)--获取指定的方法
        //--1是指方法名--2是指方法需要的参数类型的class对象
        Method m = a.getDeclaredMethod("game", String.class);
        //暴力反射：除了用对API，另外还需要开启访问权限
        m.setAccessible(true);
        Object obj = a.newInstance();
        //执行方法--invoke（1,2）--1是指对象名称--2是方法需要传入的参数
        m.invoke(obj, "天下");
        Method m1 = a.getDeclaredMethod("show");
        m1.invoke(obj, null);


    }
    //暴力反射成员变量
    public static void method2() throws Exception {
        Class a = Person.class;
        //获取所有成员变量--只能获取公开的变量
        Field[] fs = a.getDeclaredFields();
        for (Field f : fs) {
            System.out.println(f.getName());
            System.out.println(f.getType().getName());
        }
        //获取指定的变量
        Field f = a.getDeclaredField("score");
        f.setAccessible(true);
        Object obj=a.newInstance();
        //设置值--set(1,2)--1是指对象名称--2是要设置的具体指
        f.set(obj,99.9);
        //获取值--get（1）--1是指对象名称
        System.out.println(f.get(obj));



    }
}
